package org.jim.server.command.handler;

import org.apache.commons.lang3.StringUtils;
import org.jim.core.ImChannelContext;
import org.jim.core.ImPacket;
import org.jim.core.ImStatus;
import org.jim.core.config.ImConfig;
import org.jim.core.exception.ImException;
import org.jim.core.packets.*;
import org.jim.server.ImServerChannelContext;
import org.jim.server.JimServer;
import org.jim.server.JimServerAPI;
import org.jim.server.command.AbstractCmdHandler;
import org.jim.server.config.ImServerConfig;
import org.jim.server.protocol.ProtocolManager;
import org.jim.server.queue.MsgQueueRunnable;
import org.jim.server.util.GeneralMsgKit;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Objects;

/**
 * 版本: [1.0]
 * 功能说明: 通用消息cmd消息命令处理器
 * @author : WChao 创建时间: 2017年9月22日 下午2:58:59
 */
public class GeneralMsgReqHandler extends AbstractCmdHandler {

	private static Logger log = LoggerFactory.getLogger(GeneralMsgReqHandler.class);

	@Override
	public ImPacket handler(ImPacket packet, ImChannelContext channelContext) throws ImException {
		String userid = channelContext.getTioChannelContext().userid;
		if(userid == null) {
			ImPacket respChatPacket = ProtocolManager.Packet.notlogged(channelContext);
			return respChatPacket;
		}
		ImServerChannelContext imServerChannelContext = (ImServerChannelContext)channelContext;
		if (packet.getBody() == null) {
			throw new ImException("body is null");
		}
		GeneralMsgBody generalMsgBody = GeneralMsgKit.toGeneralMsgBody(packet.getBody(), channelContext);
		packet.setBody(generalMsgBody.toByte());
		//聊天数据格式不正确
		if(generalMsgBody == null || ChatType.forNumber(generalMsgBody.getChatType()) == null){
			ImPacket respChatPacket = ProtocolManager.Packet.dataInCorrect(channelContext);
			return respChatPacket;
		}
		//异步调用业务处理消息接口
		MsgQueueRunnable msgQueueRunnable = getMsgQueueRunnable(imServerChannelContext);
		msgQueueRunnable.addMsg(generalMsgBody);
		msgQueueRunnable.executor.execute(msgQueueRunnable);
		ImPacket chatPacket = new ImPacket(Command.COMMAND_GENERALMSG_REQ,new RespBody(Command.COMMAND_GENERALMSG_RESP,generalMsgBody).toByte());
		//设置同步序列号;
		chatPacket.setSynSeq(packet.getSynSeq());
		ImServerConfig imServerConfig = ImConfig.Global.get();
		boolean isStore = ImServerConfig.ON.equals(imServerConfig.getIsStore());
		String groupId = generalMsgBody.getGroupId();//获取群组id
		String localId = generalMsgBody.getLocalId();//获取客户端消息id

		//私聊
		if(ChatType.CHAT_TYPE_PRIVATE.getNumber() == generalMsgBody.getChatType()){
//			String toId = generalMsgBody.getTo();
//			if(ChatKit.isOnline(toId, isStore)){
//				JimServerAPI.sendToUser(toId, chatPacket);
//				//发送成功响应包
//				return ProtocolManager.Packet.success(channelContext);
//			}else{
//				//用户不在线响应包
//				return ProtocolManager.Packet.offline(channelContext);
//			}
			//群聊
		}else if(ChatType.CHAT_TYPE_PUBLIC.getNumber() == generalMsgBody.getChatType()){
			RespBody resPacket = new RespBody(Command.COMMAND_GENERALMSG2_RESP);
//			//发送成功响应包
//			RespBody resPacket = new RespBody(Command.COMMAND_GENERALMSG_RESP);
//			resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg());//默认返回C10000，根据业务需求再改
//			resPacket.setData(generalMsgBody);
//			if(StringUtils.isEmpty(groupId)){
//				resPacket.setCode(ImStatus.C10026.getCode()).setMsg(ImStatus.C10026.getMsg());
//				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
//			}
			log.info("从传参里取出body为="+packet.getBody());
			if(generalMsgBody.getInstruct() == InstructId.TurnOnTheCamera.getNumber()){//打开摄像头
				//给群组发消息
				JimServerAPI.sendToGroup(groupId, chatPacket);
				//发送成功响应包
				resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg()).
						setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
			}else if(generalMsgBody.getInstruct() == InstructId.TurnOnAllCamera.getNumber()){//打开所有人摄像头
				//给群组发消息
				JimServerAPI.sendToGroup(groupId, chatPacket);

				//发送成功响应包
				resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg()).
						setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
				//发送成功响应包
				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
			}else if(generalMsgBody.getInstruct() == InstructId.TurnOffTheCamera.getNumber()){//关闭所有人摄像头
				//给群组发消息
				JimServerAPI.sendToGroup(groupId, chatPacket);
				//发送成功响应包
				resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg()).
						setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
			}else if(generalMsgBody.getInstruct() == InstructId.TurnOffAllCamera.getNumber()){//关闭所有人摄像头
				//给群组发消息
				JimServerAPI.sendToGroup(groupId, chatPacket);
				//发送成功响应包
				resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg()).
						setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
			}else if(generalMsgBody.getInstruct() == InstructId.TurnOnTheMicrophone.getNumber()){//打开麦克风
				//给群组发消息
				JimServerAPI.sendToGroup(groupId, chatPacket);
				//发送成功响应包
				resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg()).
						setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
			}else if(generalMsgBody.getInstruct() == InstructId.TurnOnAllMicrophone.getNumber()){//打开所有人麦克风
				//给群组发消息
				JimServerAPI.sendToGroup(groupId, chatPacket);
				//发送成功响应包
				resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg()).
						setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
			}else if(generalMsgBody.getInstruct() == InstructId.TurnOffTheMicrophone.getNumber()){//关闭麦克风
				//给群组发消息
				JimServerAPI.sendToGroup(groupId, chatPacket);
				//发送成功响应包
				resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg()).
						setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
			}else if(generalMsgBody.getInstruct() == InstructId.TurnOffAllMicrophone.getNumber()){//关闭所有人麦克风
				//给群组发消息
				JimServerAPI.sendToGroup(groupId, chatPacket);
				//发送成功响应包
				resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg()).
						setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
			} else if(generalMsgBody.getInstruct() == InstructId.EnterTheRoom.getNumber()){//进入房间

				//绑定群组
				JimServerAPI.bindGroup(channelContext, groupId);
				//给群组发消息
				JimServerAPI.sendToGroup(groupId, chatPacket);
				//发送成功响应包
				resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg()).
						setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
			} else if(generalMsgBody.getInstruct() == InstructId.LeaveTheRoom.getNumber()){//离开房间
				String userId = generalMsgBody.getUserId();
				if(StringUtils.isEmpty(userId)){
					//发送成功响应包
					resPacket.setCode(ImStatus.C10027.getCode()).setMsg(ImStatus.C10027.getMsg()).
							setData(generalMsgBody).setLocalId(localId);
					return ProtocolManager.Converter.respPacket(resPacket, channelContext);
				}
				//将指定用户从指定群组解除绑定
				JimServerAPI.unbindGroup(userId,groupId);
				//给群组发消息
				JimServerAPI.sendToGroup(groupId, chatPacket);
				//发送成功响应包
				resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg()).
						setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
			}else if(generalMsgBody.getInstruct() == InstructId.CloseMeeting.getNumber()){// 结束会议
				//给群组发消息
				JimServerAPI.sendToGroup(groupId, chatPacket);
				//解散群组
				JimServerAPI.dissGroup(groupId);
				//发送成功响应包
				resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg()).
						setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
			}else if(generalMsgBody.getInstruct() == InstructId.GetKickedOutOfTheMeeting.getNumber()){//被踢出会议
				String userId = generalMsgBody.getUserId();
				if(StringUtils.isEmpty(userId)){
					//发送成功响应包
					resPacket.setCode(ImStatus.C10027.getCode()).setMsg(ImStatus.C10027.getMsg()).
							setData(generalMsgBody).setLocalId(localId);
					return ProtocolManager.Converter.respPacket(resPacket, channelContext);
				}
				//给群组发消息
				JimServerAPI.sendToGroup(groupId, chatPacket);
				//将指定用户从指定群组解除绑定
				JimServerAPI.unbindGroup(userId,groupId);
				//发送成功响应包
				resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg()).
						setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
			}else if(generalMsgBody.getInstruct() == InstructId.chageName.getNumber()){//修改与会名称
				//给群组发消息
				JimServerAPI.sendToGroup(groupId, chatPacket);
				//发送成功响应包
				resPacket.setCode(ImStatus.C10000.getCode()).setMsg(ImStatus.C10000.getMsg()).
						setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
				return ProtocolManager.Converter.respPacket(resPacket, channelContext);
			}

		}
		//发送成功响应包
		RespBody resPacket = new RespBody(Command.COMMAND_GENERALMSG_RESP);
		resPacket.setCode(ImStatus.C10028.getCode()).setMsg(ImStatus.C10028.getMsg()).
				setData(generalMsgBody).setLocalId(localId);//默认返回C10000，根据业务需求再改
		return ProtocolManager.Converter.respPacket(resPacket, channelContext);
	}

	@Override
	public Command command() {
		return Command.COMMAND_GENERALMSG_REQ;
	}

	/**
	 * 获取聊天业务处理异步消息队列
	 * @param imServerChannelContext IM通道上下文
	 * @return
	 */
	private MsgQueueRunnable getMsgQueueRunnable(ImServerChannelContext imServerChannelContext){
		MsgQueueRunnable msgQueueRunnable = (MsgQueueRunnable)imServerChannelContext.getMsgQue();
		if(Objects.nonNull(msgQueueRunnable.getProtocolCmdProcessor())){
			return msgQueueRunnable;
		}
		synchronized (MsgQueueRunnable.class){
			msgQueueRunnable.setProtocolCmdProcessor(this.getSingleProcessor());
		}
		return msgQueueRunnable;
	}

}
